// CommandLineHelper Library
// =========================
// License: Microsoft Permissive License (Ms-PL) v1.1
// Author: Rhy Mednick (http://www.rhyverse.net)
// Project Site: http://www.codeplex.com/CommandLineHelper

using System;
using System.Collections.Generic;
using System.Text;

namespace CommandLineHelper.Attributes
{
    /// When applied to a property, this attribute instructs the command line helper parsing routine to validate 
    /// that the property value passed in is within the range of values specified.
    [AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)]
    public sealed class ValidateRangeAttribute : Attribute, IValidation 
    {
        private long m_maxRange = long.MaxValue;
        private long m_minRange = long.MinValue;
        private string m_statusMessage = String.Empty;

        /// <summary>
        /// Gets the status message that is set when the IsValid() method is called.
        /// </summary>
        public string StatusMessage
        {
            get
            {
                return m_statusMessage;
            }
        }

        /// <summary>
        /// Gets or sets the maximum value for the property.
        /// </summary>
        public long MaxRange
        {
            get { return m_maxRange; }
            set 
            {
                if (value > this.MinRange)
                {
                    m_maxRange = value;
                }
                else
                {
                    throw new ArgumentException("The max range cannot be set to a value lower than or equal to the minimum range.");
                }
            }
        }

        /// <summary>
        /// Gets or sets the minimum value for the property.
        /// </summary>
        public long MinRange
        {
            get { return m_minRange; }
            set 
            {
                if (value < this.MaxRange)
                {
                    m_minRange = value;
                }
                else
                {
                    throw new ArgumentException("the min range cannot be set to a value that is greater than or equal to the maximum range.");
                }
            }
        }

        /// <summary>
        /// Verifies that the value is within the range defined in the MinRange and MaxRange properties.
        /// </summary>
        /// <param name="value">The value to validate.</param>
        /// <returns>True if the value is within the allowable range and false if it isn't.</returns>
        public bool IsValid(object value)
        {
            bool retval = false;

            //this is only a valid test for numeric types, so verify that we're numeric
            Type type = value.GetType();
            if (type.IsValueType)
            {
                long longVal = (long)Convert.ChangeType(value, typeof(long));
                //i think that all value types are numeric.  if i'm wrong then we'll get an exception
                if (longVal <= this.MaxRange && longVal >= this.MinRange)
                {
                    retval = true;
                }
            }

            return retval;
        }
    }
}
